home *** CD-ROM | disk | FTP | other *** search
/ Plug-In Power Pack for Netscape Communicator / Plug-In Power Pack for Netscape Communicator.iso / plugins / dataviews / dvtools / demos / telecomdemo / do_simul.c < prev    next >
C/C++ Source or Header  |  1997-07-10  |  15KB  |  555 lines

  1. #ifndef lint
  2. static char SccsId[]= "@(#)do_simul.c    V1.13    5/2/95";
  3. #endif
  4.  
  5. /*
  6.  |    File name: do_simul.c
  7.  |========================================================================
  8.  |
  9.  |    Copyright (c) 1990 -- V.I. Corporation
  10.  |
  11.  |========================================================================
  12.  */
  13. #include "std.h"
  14. #include "simulate.h"
  15. #include "tlc_fundecl.h"
  16.  
  17.  
  18. /***************** Begin Function Declarations *************/
  19. LOCAL  void ClearPartStatus V_P_((char *part_name, PART_STRUCT *part_struct, ADDRESS args));
  20. LOCAL  void ClearNodeStatus V_P_((char *node_name, NODE_STRUCT *node_struct, ADDRESS args));
  21. LOCAL  void ClearLinkStatus V_P_((char *link_name, LINK_STRUCT *link_struct, ADDRESS args));
  22. LOCAL  void ForceError V_P_((void));
  23. LOCAL  void UpdateParts V_P_((char *part_name, PART_STRUCT *part_struct, ADDRESS args));
  24. LOCAL  void RecordError V_P_((PART_STRUCT *part_struct));
  25. LOCAL  void UpdateLinks V_P_((char *link_name, LINK_STRUCT *link_struct, ADDRESS args));
  26. LOCAL  void UpdateNodes V_P_((VIEW_STRUCT *view_struct));
  27. LOCAL  int ComputeNodeStatus V_P_((NODE_STRUCT *node_struct));
  28. LOCAL  int RandomError V_P_((char *part_name));
  29. LOCAL  int GetParentNodeStatus V_P_((PART_STRUCT *part_struct));
  30. /***************** End Function Declarations *************/
  31.  
  32. /*
  33.  *   StartSimulation -- start the simulation.  Reset the iteration number,
  34.  *     set the status of ll network components to normal, and draw the
  35.  *     top level view.
  36.  */
  37. void StartSimulation 
  38. V_P_ ((void))
  39. {
  40.   SimParams.iter_number = 1;
  41.   VTsttraverse (SimParams.switch_tab, (VTSTTRAVERSEFUNPTR) ClearPartStatus, 
  42.         (ADDRESS) NULL);
  43.   VTsttraverse (SimParams.part_tab, (VTSTTRAVERSEFUNPTR) ClearPartStatus, 
  44.         (ADDRESS) NULL);
  45.   VTsttraverse (SimParams.node_tab, (VTSTTRAVERSEFUNPTR) ClearNodeStatus, 
  46.         (ADDRESS) NULL);
  47.   VTsttraverse (SimParams.link_tab, (VTSTTRAVERSEFUNPTR) ClearLinkStatus, 
  48.         (ADDRESS) NULL);
  49.   if (SimParams.curr_view)
  50.     NewMainView (SimParams.curr_view, SimParams.top_view);
  51.   else
  52.     NewMainView ((VIEW_STRUCT *) NULL, SimParams.top_view);
  53. }
  54.  
  55.  
  56. /*
  57.  *   ClearPartStatus -- used by traversal routine to set the status
  58.  *     of a part to normal.
  59.  */
  60. /* ARGSUSED */
  61. LOCAL void 
  62. ClearPartStatus (part_name, part_struct, args)
  63.      char *part_name;
  64.      PART_STRUCT *part_struct;
  65.      ADDRESS args;
  66. {
  67.   part_struct->status = NORMAL;
  68. }
  69.  
  70.  
  71. /*
  72.  *   ClearNodeStatus -- called by traversal routine to return the
  73.  *     status of all nodes to normal, and to clear the error counters.
  74.  */
  75. /* ARGSUSED */
  76. LOCAL void 
  77. ClearNodeStatus (node_name, node_struct, args)
  78.      char *node_name;
  79.      NODE_STRUCT *node_struct;
  80.      ADDRESS args;
  81. {
  82.   node_struct->status = NORMAL;
  83.   node_struct->failure_count = 0;
  84.   node_struct->critical_count = 0;
  85.   node_struct->softerror_count = 0;
  86. }
  87.  
  88.  
  89. /*
  90.  *   ClearLinkStatus -- called by traversal routine to change the status
  91.  *     of links to normal.
  92.  */
  93. /* ARGSUSED */
  94. LOCAL void 
  95. ClearLinkStatus (link_name, link_struct, args)
  96.      char *link_name;
  97.      LINK_STRUCT *link_struct;
  98.      ADDRESS args;
  99. {
  100.   link_struct->status = NORMAL;
  101. }
  102.  
  103.  
  104. /*
  105.  *   NextSimulationStep -- perform the next step in the simulation.  Check
  106.  *     for a restart, check for a forced error, and update the status of all
  107.  *     network components.
  108.  */
  109. void NextSimulationStep 
  110. V_P_ ((void))
  111. {
  112.   /*
  113.    *   If the restart flag has been set, then reset the subviews, restart
  114.    *     the simulation, and clear the restart flag.
  115.    */
  116.   if (*Control.restart_flag)
  117.     {
  118.       ResetSubviews ();
  119.       StartSimulation ();
  120.       *Control.restart_flag = 0;
  121.       return;
  122.     }
  123.  
  124.   /*
  125.    *   Update the interation number, force an error if the flag is set.
  126.    *     Otherwise, update the status of the parts and switches, and then
  127.    *     update the status of the nodes and links.
  128.    */
  129.   SimParams.iter_number++;
  130.   if (*Control.force_error_flag)
  131.     {
  132.       ForceError ();
  133.       *Control.force_error_flag = 0;
  134.     }
  135.   else
  136.     {
  137.       VTsttraverse (SimParams.switch_tab, (VTSTTRAVERSEFUNPTR) UpdateParts,
  138.             (ADDRESS) NULL);
  139.       VTsttraverse (SimParams.part_tab, (VTSTTRAVERSEFUNPTR) UpdateParts,
  140.             (ADDRESS) NULL);
  141.     }
  142.   VTsttraverse (SimParams.link_tab, (VTSTTRAVERSEFUNPTR) UpdateLinks,
  143.         (ADDRESS) NULL);
  144.   UpdateNodes (SimParams.top_view);
  145. }
  146.  
  147.  
  148. /*
  149.  *   ForceError -- force an error in one of the switches.  Pick one
  150.  *     of the switches at random and change its status to failure.
  151.  */
  152. LOCAL void ForceError 
  153. V_P_ ((void))
  154. {
  155.   INT switchno, num_switches;
  156.   PART_STRUCT *part_struct;
  157.   SYMNODE symnode;
  158.  
  159.   num_switches = VTstlen (SimParams.switch_tab);
  160.   switchno = (INT) (num_switches * VUfrand ());
  161.   symnode = VTstsnget (SimParams.switch_tab, switchno);
  162.   part_struct = (PART_STRUCT *) VTsnvalue (symnode);
  163.   part_struct->status = FULL_FAILURE;
  164.   RecordError (part_struct);
  165. }
  166.  
  167.  
  168. /*
  169.  *   UpdateParts -- change the status of all parts and switches.
  170.  *     If the part is already broken, then check to see if the part
  171.  *     needs to be fixed automatically.  Otherwise, use a random
  172.  *     function to get a new part status.
  173.  */
  174. /* ARGSUSED */
  175. LOCAL void 
  176. UpdateParts (part_name, part_struct, args)
  177.      char *part_name;
  178.      PART_STRUCT *part_struct;
  179.      ADDRESS args;
  180. {
  181.   if (part_struct->status == MAJOR_CRITICAL ||
  182.       part_struct->status == FULL_FAILURE)
  183.     {
  184.       /*
  185.        *   If enough time has passed since the part has broken then it
  186.        *     should be autofixed.  Or, if the part has been scheduled to
  187.        *     be fixed, then check to see if that time has arrived.
  188.        */
  189.       if ((part_struct->error_time + (INT) (*Control.autofix_delay)) <
  190.           SimParams.iter_number)
  191.         {
  192.           part_struct->status = NORMAL;
  193.           OutputInfo ((INT) SimParams.iter_number, FIX_DONE,
  194.                       part_struct->part_name, "Otto");
  195.         }
  196.       else if (part_struct->fix_time == SimParams.iter_number)
  197.         {
  198.           part_struct->status = NORMAL;
  199.           OutputInfo ((INT) SimParams.iter_number, FIX_DONE,
  200.                       part_struct->part_name, (CHAR *) NULL);
  201.         }
  202.     }
  203.   else
  204.     {
  205.       part_struct->status = RandomError (part_struct->part_name);
  206.       RecordError (part_struct);
  207.     }
  208. }
  209.  
  210.  
  211. /*
  212.  *   RecordError -- check the status of the part and update the correct
  213.  *     counter in the parent node.
  214.  */
  215. LOCAL void 
  216. RecordError (part_struct)
  217.      PART_STRUCT *part_struct;
  218. {
  219.   NODE_STRUCT *node_struct;
  220.  
  221.   node_struct = part_struct->primary_node;
  222.   switch (part_struct->status)
  223.     {
  224.     case SOFT_ERROR:
  225.       part_struct->status = NORMAL;
  226.       node_struct->softerror_count++;
  227.       OutputInfo ((INT) SimParams.iter_number, SOFT,
  228.                   part_struct->part_name, (CHAR *) NULL);
  229.       break;
  230.     case MAJOR_CRITICAL:
  231.       node_struct->critical_count++;
  232.       part_struct->error_time = SimParams.iter_number;
  233.       OutputInfo ((INT) SimParams.iter_number, CRITICAL,
  234.                   part_struct->part_name, (CHAR *) NULL);
  235.       break;
  236.     case FULL_FAILURE:
  237.       node_struct->failure_count++;
  238.       part_struct->error_time = SimParams.iter_number;
  239.       OutputInfo ((INT) SimParams.iter_number, FULL_FAIL,
  240.                   part_struct->part_name, (CHAR *) NULL);
  241.       break;
  242.     default:
  243.       break;
  244.     }
  245. }
  246.  
  247. #define ERROR_POS    8
  248. #define WHERE_POS    28
  249. #define WHAT_POS    45
  250. #define WHO_POS        55
  251.  
  252. void 
  253. OutputInfo (iter_num, type, part_name, ident)
  254.      int iter_num;
  255.      int type;
  256.      char *part_name;
  257.      char *ident;
  258. {
  259.   INT i;
  260.   CHAR msg[255];
  261.   CHAR *name;
  262.   CHAR *ptr, *next_tok;
  263.   CHAR *what, *where;
  264.   VIEW_STRUCT *view_struct;
  265.   NODE_STRUCT *node_struct;
  266.  
  267.   msg[0] = 0;
  268.   name = StrClone (part_name);
  269.   get_token (name, &ptr, &next_tok);
  270.  
  271. #ifdef WINNT 
  272.   (VOID)sprintf( msg, "%5d", iter_num );
  273. #else  /*Not WINNT */
  274.   (VOID) sprintf (msg, "%d\t", iter_num);
  275. #endif /* WINNT */
  276.  
  277.   for (i = strlen (msg); i < ERROR_POS; i++)
  278.     msg[i] = ' ';
  279.  
  280.   if (strncmp (ptr, "switch", 6) == 0)
  281.     {
  282.       what = "switch";
  283.       where = next_tok;
  284.     }
  285.   else
  286.     {
  287.       view_struct = GetNamedView (ptr);
  288.       node_struct = view_struct->back_ptr;
  289.       where = node_struct->node_name;
  290.       what = next_tok;
  291.     }
  292.  
  293.   switch (type)
  294.     {
  295.     case SOFT:
  296.       (VOID) sprintf (&msg[ERROR_POS], "SOFT ERROR");
  297.       break;
  298.     case CRITICAL:
  299.       (VOID) sprintf (&msg[ERROR_POS], "CRITICAL ERROR");
  300.       break;
  301.     case FULL_FAIL:
  302.       (VOID) sprintf (&msg[ERROR_POS], "FULL FAILURE");
  303.       break;
  304.     case FIX_ORDER:
  305.       (VOID) sprintf (&msg[ERROR_POS], "FIX ORDER");
  306.       break;
  307.     case FIX_DONE:
  308.       (VOID) sprintf (&msg[ERROR_POS], "FIX COMPLETED");
  309.       break;
  310.     }
  311.   for (i = strlen (msg); i < WHERE_POS; i++)
  312.     msg[i] = ' ';
  313.  
  314.   (VOID) sprintf (&msg[WHERE_POS], "%s", where);
  315.   for (i = strlen (msg); i < WHAT_POS; i++)
  316.     msg[i] = ' ';
  317.  
  318.   (VOID) sprintf (&msg[WHAT_POS], "%s", what);
  319.   for (i = strlen (msg); i < WHO_POS; i++)
  320.     msg[i] = ' ';
  321.  
  322.   if (ident)
  323.     (VOID) sprintf (&msg[WHO_POS], "By: %s", ident);
  324.   else
  325.     msg[WHO_POS] = '\0';
  326.  
  327.   OutputLog (msg);
  328.   S_FREE (name);
  329. }
  330.  
  331.  
  332. /*
  333.  *   UpdateLinks -- update the status of a link based on its switches.
  334.  *     If either or both of a link's switches exist, then compute the link's
  335.  *     status based on the status of the switches.
  336.  */
  337. /* ARGSUSED */
  338. LOCAL void 
  339. UpdateLinks (link_name, link_struct, args)
  340.      char *link_name;
  341.      LINK_STRUCT *link_struct;
  342.      ADDRESS args;
  343. {
  344.   PART_STRUCT *switch1, *switch2;
  345.   SHORT status;
  346.  
  347.   status = NORMAL;
  348.   switch1 = link_struct->switch1;
  349.   switch2 = link_struct->switch2;
  350.   if (switch1)
  351.     status |= switch1->status;
  352.   if (switch2)
  353.     status |= switch2->status;
  354.   link_struct->status = status;
  355. }
  356.  
  357.  
  358. /*
  359.  *   UpdateNodes -- update the status of all nodes in a view.  Traverse
  360.  *     the list of nodes in a view, computing new statuses for each.
  361.  */
  362. LOCAL void 
  363. UpdateNodes (view_struct)
  364.      VIEW_STRUCT *view_struct;
  365. {
  366.   NODE_STRUCT *node_struct;
  367.  
  368.   node_struct = view_struct->node_list;
  369.   while (node_struct != NULL)
  370.     {
  371.       node_struct->status |= ComputeNodeStatus (node_struct);
  372.       node_struct = node_struct->next;
  373.     }
  374. }
  375.  
  376.  
  377. /*
  378.  *   ComputeNodeStatus -- compute the status of a node.  If the node has
  379.  *     subnodes, then compute the status of this node based on the status
  380.  *     of all of its subnodes.  If the node has no subnodes, compute its
  381.  *     status based on the status of its parts.
  382.  */
  383. LOCAL int 
  384. ComputeNodeStatus (node_struct)
  385.      NODE_STRUCT *node_struct;
  386. {
  387.   VIEW_STRUCT *view_struct;
  388.   PART_STRUCT *part_ptr;
  389.   NODE_STRUCT *sec_node_struct;
  390.   SHORT status;
  391.  
  392.   /*
  393.    *   If the node has no subview, then keep its status as normal.
  394.    */
  395.   view_struct = node_struct->view_ptr;
  396.   if (view_struct == NULL)
  397.     return NORMAL;
  398.  
  399.   /*
  400.    *   If the node has no subnodes, then figure the status of the node
  401.    *     from its component parts.
  402.    */
  403.   if (view_struct->node_list == NULL)
  404.     {
  405.       part_ptr = view_struct->part_list;
  406.       node_struct->status = NORMAL;
  407.       while (part_ptr != NULL)
  408.         {
  409.           node_struct->status |= GetParentNodeStatus (part_ptr);
  410.           part_ptr = part_ptr->next;
  411.         }
  412.       return node_struct->status;
  413.     }
  414.   else
  415.     {
  416.       /*
  417.        *   If the node has subnodes, then compute the node status
  418.        *     based on the composite status of the subnodes and the
  419.        *     severity of the error.
  420.        */
  421.       sec_node_struct = view_struct->node_list;
  422.       status = NORMAL;
  423.       while (sec_node_struct != NULL)
  424.         {
  425.           status |= ComputeNodeStatus (sec_node_struct);
  426.           sec_node_struct = sec_node_struct->next;
  427.         }
  428.       if (status & FULL_FAILURE)
  429.         node_struct->status = MAJOR_CRITICAL;
  430.       else if (status & MAJOR_CRITICAL)
  431.         node_struct->status = MAJOR_CRITICAL;
  432.       else if (status & MINOR_CRITICAL)
  433.         node_struct->status = MINOR_WARNING;
  434.       else if (status & MAJOR_WARNING)
  435.         node_struct->status = MAJOR_WARNING;
  436.       else
  437.         node_struct->status = NORMAL;
  438.     }
  439.   return node_struct->status;
  440. }
  441.  
  442.  
  443. /*
  444.  *   Define error frequency based on number of errors per 30 iterations.
  445.  */
  446. #define NUM_FAILURES    3
  447. #define NUM_CRITICALS    6
  448. #define NUM_SOFTERRORS    21
  449. #define TOT_ERRORS    30
  450.  
  451. /*
  452.  *   RandomError -- compute an status based on random values.  Compute
  453.  *     the new status based on the error frequencies, the error factor
  454.  *     set by the user, and a random value.
  455.  */
  456. /* ARGSUSED */
  457. LOCAL int 
  458. RandomError (part_name)
  459.      char *part_name;
  460. {
  461.   INT chances, range;
  462.   FLOAT setpoint, result;
  463.  
  464.   chances = SimParams.total_parts * 100;
  465.   range = (chances * 2) - (chances / 2);
  466.   setpoint = (FLOAT)((chances / 2) +
  467.     (range * ((100.0 - *Control.error_factor) / 100.0)));
  468.   result = (FLOAT)(setpoint * VUfrand ());
  469.   if (result < TOT_ERRORS)
  470.     {
  471.       if (result < NUM_FAILURES)
  472.         return FULL_FAILURE;
  473.       if (result < (NUM_FAILURES + NUM_CRITICALS))
  474.         return MAJOR_CRITICAL;
  475.       else
  476.         return SOFT_ERROR;
  477.     }
  478.   else
  479.     return NORMAL;
  480. }
  481.  
  482.  
  483. /*
  484.  *   GetParentNodeStatus -- compute the status of the parent node based on
  485.  *     the status of the part and the inheritence properties of the part.
  486.  */
  487. LOCAL int 
  488. GetParentNodeStatus (part_struct)
  489.      PART_STRUCT *part_struct;
  490. {
  491.   SHORT status;
  492.  
  493.   /*
  494.    *   If the part status is normal or one of the warning values, then
  495.    *     the node assumes the same status.
  496.    */
  497.   status = part_struct->status;
  498.   if (status == (SHORT) NORMAL)
  499.     return (SHORT) NORMAL;
  500.   else if (status == (SHORT) MAJOR_WARNING)
  501.     return (SHORT) MAJOR_WARNING;
  502.   else if (status == (SHORT) MINOR_WARNING)
  503.     return (SHORT) MINOR_WARNING;
  504.  
  505.   /*
  506.    *   If the status is major critical then return the status of the
  507.    *     parent node based on the values in the inheritence string.
  508.    */
  509.   else if (status == (SHORT) MAJOR_CRITICAL)
  510.     switch (part_struct->err_prop[1])
  511.       {
  512.       case 'c':
  513.         if (part_struct->err_prop[2] == '+')
  514.           return (SHORT) MAJOR_CRITICAL;
  515.         else
  516.           return (SHORT) MINOR_CRITICAL;
  517.         break;
  518.       case 'w':
  519.         if (part_struct->err_prop[2] == '+')
  520.           return (SHORT) MAJOR_WARNING;
  521.         else
  522.           return (SHORT) MINOR_WARNING;
  523.         break;
  524.       default:
  525.         return (SHORT) NORMAL;
  526.       }
  527.  
  528.   /*
  529.    *   If the status is full failure then return the status of the
  530.    *     parent node based on the values in the inheritence string.
  531.    */
  532.   else if (status == (SHORT) FULL_FAILURE)
  533.     switch (part_struct->err_prop[0])
  534.       {
  535.       case 'f':
  536.         return (SHORT) FULL_FAILURE;
  537.         break;
  538.       case 'c':
  539.         if (part_struct->err_prop[2] == '+')
  540.           return (SHORT) MAJOR_CRITICAL;
  541.         else
  542.           return (SHORT) MINOR_CRITICAL;
  543.         break;
  544.       case 'w':
  545.         if (part_struct->err_prop[2] == '+')
  546.           return (SHORT) MAJOR_WARNING;
  547.         else
  548.           return (SHORT) MINOR_WARNING;
  549.         break;
  550.       default:
  551.         return (SHORT) NORMAL;
  552.       }
  553.   return (SHORT) NORMAL;
  554. }
  555.